package com.tsfyun.scm.service.impl.system;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import com.tsfyun.common.base.config.OrikaBeanMapper;
import com.tsfyun.common.base.enums.MenuTypeEnum;
import com.tsfyun.common.base.enums.core.SectionModuleEnum;
import com.tsfyun.common.base.extension.ServiceImpl;
import com.tsfyun.common.base.security.LoginVO;
import com.tsfyun.common.base.security.SecurityUtil;
import com.tsfyun.common.base.security.SysRoleVO;
import com.tsfyun.common.base.support.DomainStatus;
import com.tsfyun.common.base.support.OperationInfo;
import com.tsfyun.common.base.util.StringUtils;
import com.tsfyun.scm.entity.system.SysMenu;
import com.tsfyun.scm.entity.system.SysRole;
import com.tsfyun.scm.mapper.system.SysMenuMapper;
import com.tsfyun.scm.service.system.ISysMenuService;
import com.tsfyun.scm.service.system.ISysRoleService;
import com.tsfyun.scm.util.AuthUserUtil;
import com.tsfyun.scm.util.UITree;
import com.tsfyun.scm.vo.system.SimpleSysMenuVO;
import com.tsfyun.scm.vo.system.SysMenuVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@RefreshScope
@Slf4j
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenu> implements ISysMenuService {

    @Autowired
    private ISysRoleService sysRoleService;

    @Autowired
    private SysMenuMapper sysMenuMapper;

    @Value("${scm.manage.person.code}")
    private String managePersonCode;

    @Value("${scm.manage.role.code}")
    private String manageRoleCode;

    @Autowired
    private OrikaBeanMapper beanMapper;

    //导航菜单类型
    private static final List navigationMenuType = Lists.newArrayList(1,2);

    //所有菜单类型
    private static final List allMenuType = Lists.newArrayList(1,2,3);

    //按钮菜单类型
    private static final List buttonMenuType = Lists.newArrayList(3);

    @Override
    public List<UITree> getBackgroundUserMenu() {
        List<SysMenu> menus;
        LoginVO loginVO =  SecurityUtil.getCurrent();
        //获取用户角色
        List<SysRole> roles = sysRoleService.getUserRoles(loginVO.getPersonId());
        boolean isAdmin = AuthUserUtil.checkIsAdmin(beanMapper.mapAsList(roles,SysRoleVO.class),loginVO,manageRoleCode,managePersonCode);
        log.info("当前登录用户:{}，是否管理员:{}",loginVO.getLoginName(),isAdmin ? "是" : "否");
        if(isAdmin) {
            menus = sysMenuMapper.getAllMenu(navigationMenuType);
        } else {
            menus = sysMenuMapper.findByPersonIdAndTypeAndParentId(navigationMenuType,loginVO.getPersonId(),null);
        }
        return UITree.buildTree(menus);
    }

    @Override
    public List<UITree> getSectionBackgroundUserMenu(String sectionModule) {
        SectionModuleEnum sectionModuleEnum = SectionModuleEnum.of(sectionModule);
        if(Objects.isNull(sectionModuleEnum)) {
            return getBackgroundUserMenu();
        }
        //搜索包含本版块的，不属于任何版块的
        List<String> allSection = Arrays.asList(SectionModuleEnum.values()).stream().map(SectionModuleEnum::getName).collect(Collectors.toList());
        List<String> otherSection = allSection.stream().filter(r->!Objects.equals(r,sectionModuleEnum.getName())).collect(Collectors.toList());
        List<UITree> sectionUITrees = Lists.newArrayList();
        List<UITree> uiTrees = getBackgroundUserMenu();
        uiTrees.stream().forEach(uiTree -> {
            List<UITree> childs = uiTree.getChilds();
            List<UITree> sectionChilds = Lists.newArrayList();
            childs.stream().forEach(child->{
                String childMenuName = child.getName();
                if(childMenuName.contains(sectionModuleEnum.getName())) { //包含版块名称
                    sectionChilds.add(child);
                } else { //不包含版块名称
                    otherSection.stream().forEach(r->{
                        if(!childMenuName.contains(r)) {
                            sectionChilds.add(child);
                        }
                    });
                }
            });
            uiTree.setChilds(sectionChilds);
            sectionUITrees.add(uiTree);
        });
        return sectionUITrees;
    }

    @Override
    public List<SimpleSysMenuVO> getAllMenusByRole(SysRole sysRole) {
        List<SysMenu> menus = Lists.newArrayList();
        if(Objects.equals(sysRole.getId(),manageRoleCode)) {
            menus = sysMenuMapper.getAllMenu(allMenuType);
        } else {
            menus = sysMenuMapper.findByRoleIdAndType(allMenuType,sysRole.getId());
        }
        return beanMapper.mapAsList(menus,SimpleSysMenuVO.class);
    }

    @Override
    public List<SysMenuVO> getButtonMenusByMenuId(String menuId) {
        List<SysMenu> menus = null;
        //特殊处理，如果是超级管理员组或者管理员
        //获取用户的角色信息
        LoginVO loginVO =  SecurityUtil.getCurrent();
        //获取用户角色
        List<SysRole> roles = sysRoleService.getUserRoles(loginVO.getPersonId());
        boolean isAdmin = AuthUserUtil.checkIsAdmin(beanMapper.mapAsList(roles, SysRoleVO.class),loginVO,manageRoleCode,managePersonCode);
        log.info("当前登录用户:{}，是否管理员:{}",loginVO.getLoginName(),isAdmin ? "是" : "否");
        if(isAdmin) {
            SysMenu queryCondition = new SysMenu();
            queryCondition.setType(MenuTypeEnum.BUTTON.getCode());
            queryCondition.setParentId(menuId);
            menus = super.list(queryCondition);
        } else {
            menus = sysMenuMapper.findByPersonIdAndTypeAndParentId(buttonMenuType,loginVO.getPersonId(),menuId);
        }
        if(CollectionUtil.isNotEmpty(menus)) {
            List<SysMenuVO> dataList = beanMapper.mapAsList(menus,SysMenuVO.class);
            dataList.stream().forEach(menu->{
                String operationCode = menu.getOperationCode();
                if(StringUtils.isNotEmpty(operationCode)) {
                    Map<String, OperationInfo> operationInfoMap =  DomainStatus.getInstance().getOperationMap();
                    OperationInfo operationInfo = operationInfoMap.get(operationCode);
                    if(Objects.nonNull(operationInfo) && ArrayUtil.isNotEmpty(operationInfo.getStatus())) {
                        menu.setOperationState(String.join(",",operationInfo.getStatus()));
                    }
                }
            });
            return dataList;
        }
        return null;
    }

    @Override
    public List<SimpleSysMenuVO> getAllTypeMenu() {
        List<SysMenu> menus = sysMenuMapper.getAllMenu(allMenuType);
        if(CollectionUtil.isNotEmpty(menus)) {
            return beanMapper.mapAsList(menus,SimpleSysMenuVO.class);
        }
        return null;
    }

    @Override
    public SysMenu findByOperationCode(String operationCode) {
        SysMenu condition = new SysMenu();
        condition.setOperationCode(operationCode);
        return super.getOne(condition);
    }
}
